#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "hash_map.h"
#include "map_utils.h"

#define KEY_PREFIX "tkey-"
#define VALUE_BASE 1000
#define STR_MAX_LEN 20
#define TEST_NUM 10

static unsigned int str_hash_func(void* key)
{
    return murmur_hash(key, 20);
}

static int str_equal_func(void* k1, void* k2)
{
    return (0 == memcmp(k1, k2, STR_MAX_LEN));
}

int main(int argc, const char** argv)
{
    hash_map _map;
    hash_map* m = &_map;
    map_init(m, str_hash_func, str_equal_func, 1 << 16);
    size_t str_len = STR_MAX_LEN;

    for (int i = 0; i < TEST_NUM; ++i) {
        map_entry tmp;
        tmp.key = malloc(str_len);
        memset(tmp.key, 0, str_len);
        sprintf((char*)tmp.key, KEY_PREFIX "%d", i);
        tmp.val = malloc(sizeof(unsigned int));
        int* v = (int*)tmp.val;
        *v = VALUE_BASE + i;
        map_put(m, &tmp);
    }
    for (int j = 0; j < TEST_NUM; ++j) {
        void* key = malloc(str_len);
        memset(key, 0, str_len);
        sprintf((char*)key, KEY_PREFIX "%d", j);

        map_entry* f = map_get(m, key);
        if (NULL != f) {
            printf("get a key: %s -> val: %d\n", (char*)key, *(int*)(f->val));
        }
    }

    printf("\n================================================\n");
    map_entry* e = NULL;
    map_for_each(m, e)
    {
        printf("map_for_each key: %s -> val:%d\n", (char*)e->key, *(int*)e->val);
    }
    printf("\n========================delete========================\n");

    for (int j = 0; j < TEST_NUM; ++j) {
        void* key = malloc(str_len);
        memset(key, 0, str_len);
        sprintf((char*)key, KEY_PREFIX "%d", j);

        map_entry* f = map_del(m, key);
        if (NULL != f) {
            printf("del a key: %s -> val: %d\n", (char*)key, *(int*)(f->val));
            free(f->val);
            f->val = NULL;

            free(f->key);
            f->key = NULL;

            free(f);
            f = NULL;
        }
    }

    printf("-------------after del all-----------\n");
    map_entry* e1 = NULL;
    map_for_each(m, e1)
    {
        printf("map_for_each key: %s -> val:%d\n", (char*)e1->key, *(int*)e1->val);
    }

    return EXIT_SUCCESS;
}